from uliweb.orm import *
from uliweb.core import dispatch

class Group(Model):
    name = Field(str, max_length=60, required=True, unique=True, index=True)
    caption = Field(str, max_length=80, required=True)
    managers = ManyToMany('user', collection_name='managed_groups')
    create_time = Field(datetime.datetime, auto_now_add=True)
    members_count = Field(int)
    members = ManyToMany('user', collection_name='joined_groups')
    activity = Field(int)
    icon = Field(str, max_length=255)
    description = Field(TEXT)
    categories = ManyToMany('category')
    documents = ManyToMany('document')
    documents_count = Field(int, default=0)
    
    def get_icon_url(self, small=False):
        from uliweb.contrib.upload import get_url
        from uliweb import application
        from uliweb.contrib.staticfiles import url_for_static
        from uliweb.utils.image import fix_filename
        
        if small:
            suffix = '_40x40'
        else:
            suffix = ''
        if self.icon:
            return get_url(fix_filename(self.icon, suffix), subfolder='group', application=application)
        else:
            return url_for_static(fix_filename('img/group.png', suffix))
   
def group_manager(user, group_name):
    group = find_group(group_name)
    return group.managers.has(user)

def group_member(user, group_name):
    group = find_group(group_name)
    return group.members.has(user) or group_manager(user, group_name)

def find_group(group):
    if isinstance(group, (unicode, str)):
        return Group.get(Group.c.name==group)
    else:
        assert isinstance(group, Group)
        return group

def create_group(name, caption, description='', managers=[]):
    """
    managers should be a list
    """
    from uliweb import request
    
    count = len(managers)
    group = Group(name=name, caption=caption, description=description, members_count=count)
    group.save()
    
    dispatch.call(None, 'group message', ('create', group))
    
    #the request.user should be the creator of the group
    group.managers.add(request.user)
    dispatch.call(None, 'group message', ('assign manager', group, request.user))
    
    for username in managers:
        #if the request.user.username is in managers, just skip it, because
        #we've added it already
        if request.user.username != username:
            user = User.get(username=username)
            if user:
                group.managers.add(user)
                
                dispatch.call(None, 'group message', ('assign manager', group, user))
            
    return group

def edit_group(group, caption, description, managers, user):
    group = find_group(group)
    
    group.caption = caption.strip()
    group.description = description.strip()
    group.save()

    dispatch.call(None, 'group message', ('edit', group, user))
    
    group.managers.clear()
    for username in managers:
        user = User.get(username=username)
        if user:
            group.managers.add(user)
            
            dispatch.call(None, 'group message', ('assign manager', group, user))
    
    
def join_group(group, user):
    group = find_group(group)
    if not group.managers.get(user.id) and not group.members.get(user.id):
        group.members_count += 1
        group.save()
        group.members.add(user)
        
        dispatch.call(None, 'group message', ('join', group, user))
        return True
    else:
        return False
        
def leave_group(group, user):
    group = find_group(group)
    if group.managers.get(user.id):
        group.managers.delete(user.id)
        group.members_count -= 1
        group.save()
        
        dispatch.call(None, 'group message', ('leave', group, user))
        return True
    elif group.members.get(user.id):
        group.members.delete(user.id)
        group.members_count -= 1
        group.save()
        
        dispatch.call(None, 'group message', ('leave', group, user))
        return True
    else:
        return False
        
def delete_group(group, user):
    from uliweb.contrib.upload import delete_filename

    group = find_group(group)

    dispatch.call(None, 'group message', ('delete', group, user))
    
    filename = group.icon
    group.managers.clear()
    group.members.clear()
    group.delete()
    if filename:
        delete_filename(filename)
    